import React, {useCallback, useEffect, useMemo, useState} from "react"
import DataPageLayout from "../../components/DataPageLayout";
import {Button, Form, Result, Table, Tag, Tooltip} from "antd";
import {
    createEmployee, disableEmployee,
    EmployeeResponse, enableEmployee,
    queryEmployees,
    Role,
    SUPER_ADMIN_ROLE_NAME,
    updateEmployee
} from "../../apis/EmployeeApi";
import {
    Pageable
} from "../../utils/Page";
import {getRoles, RoleResponse} from "../../apis/RoleApi";
import {castFilterValue, sorterToSort, useTableSearchTextColumnProps} from "../../utils/AntdTableUtils";
import {ArrowLeftOutlined, EditOutlined, UserAddOutlined} from "@ant-design/icons";
import EditEmployeeForm from "../../components/EditEmployeeForm";
import ActionsDrawerLayout from "../../components/ActionsDrawerLayout";
import {OffsetDateTime} from "@js-joda/core";
import employeeAuthorizationStore from "../../store/EmployeeAuthorizationStore";
import {observerDashboardPageWrapper} from "./ObserverDashboardPageWrapper";
import {DATE_WITH_TIME_FORMATER, YEAR_MONTH_DAY_FORMATER} from "../../utils/Date";
import LoadableButton from "../LoadableButton";

export interface EmployeePageProps {

}


const EmployeePage: React.FC<EmployeePageProps> = ({}) => {
    const [totalElements, setTotalElements] = useState(0)
    const [pageable, setPageable] = useState(new Pageable())
    const [data, setData] = useState<Array<EmployeeResponse>>([])
    const [loading, setLoading] = useState(false)

    const [roles, setRoles] = useState<RoleResponse[]>([])


    useEffect(() => {
        getRoles().then(res => {
            setRoles(res.data.filter(it => it.name !== SUPER_ADMIN_ROLE_NAME))
        })
    }, []);
    const phoneNumberSearchProps = useTableSearchTextColumnProps<EmployeeResponse>("phoneNumber", {
        placeholder: "手机号"
    });
    let nameSearchProps = useTableSearchTextColumnProps<EmployeeResponse>("name", {
        placeholder: "姓名"
    });
    const [searchPhoneNumberText, setSearchPhoneNumberText] = useState<string>()
    const [searchNameText, setSearchNameText] = useState<string>()
    const [roleIds, setRoleIds] = useState<number[]>([])
    const query = useCallback(() => {
        setLoading(true)
        queryEmployees(pageable, {
            phoneNumber: searchPhoneNumberText,
            name: searchNameText,
            roleIds: roleIds
        }).then(res => {
            setData(res.data.content)
            setTotalElements(res.data.totalElements)
        }).finally(() => {
            setLoading(false)
        })
    }, [...pageable.toDependencyList(), searchPhoneNumberText, searchNameText, roleIds,])
    useEffect(() => {
        query()
    }, [query]);

    const [openAddEmployeeDrawer, setOpenAddEmployeeDrawer] = useState(false)
    useEffect(() => {
        addEmployeeForm.resetFields()
        setCreatedEmployeePassword(undefined)
    }, [openAddEmployeeDrawer]);
    let [addEmployeeForm] = Form.useForm();
    const [createdEmployeePassword, setCreatedEmployeePassword] = useState<string>()
    const [createEmployeeLoading, setCreateEmployeeLoading] = useState(false)

    const [editedEmployeeId, setEditedEmployeeId] = useState<number>()
    const editedEmployeeData = useMemo(() => {
        let employee = data.find(it => it.id === editedEmployeeId);
        return employee ? {
            phoneNumber: employee.phoneNumber,
            roleIds: employee.roles.map(it => it.id),
            name: employee.name,
        } : undefined
    }, [editedEmployeeId, data]);
    const [editEmployeeLoading, setEditEmployeeLoading] = useState(false)
    let [editEmployeeForm] = Form.useForm();
    return <>
        <DataPageLayout
            rightActions={employeeAuthorizationStore.hasAuthority("人员_新增") &&
                <Button type={"primary"}
                        onClick={() => setOpenAddEmployeeDrawer(true)}>{
                    <UserAddOutlined/>}新增人员</Button>}>
            <Table loading={loading} dataSource={data}
                   size={"small"}
                   rowKey={"id"}
                   pagination={{current: pageable.page, pageSize: pageable.size, total: totalElements}}
                   onChange={(tablePagination, filters, sorter) => {
                       setPageable(Pageable.from(
                               pageable,
                               {
                                   page: tablePagination.current,
                                   size: tablePagination.pageSize,
                                   sort: sorterToSort(sorter)
                               }
                           )
                       )
                       setSearchPhoneNumberText(castFilterValue(filters.phoneNumber))
                       setSearchNameText(castFilterValue(filters.name))
                       setRoleIds(filters.roleNames as number[])
                   }}>
                <Table.Column title={"名字"} dataIndex={"name"} key={"name"} {...nameSearchProps}
                />
                <Table.Column title={"手机号"} dataIndex={"phoneNumber"}
                              key={"phoneNumber"} {...phoneNumberSearchProps}/>
                <Table.Column title={"角色"} dataIndex={"roles"} key={"roleNames"}
                              render={(roles: Role[]) => {
                                  return roles.map(role => <Tag color="gold" key={role.id}>
                                      {role.name}
                                  </Tag>)
                              }}
                              filters={roles.filter(role => role.employeeCount).map(role => {
                                  return {
                                      text: `${role.name}（${role.employeeCount}人）`,
                                      value: role.id,
                                  }
                              })}
                />
                <Table.Column title={"创建时间"} dataIndex={"createdDateTime"} key={"createdDateTime"}
                              sorter={{multiple: 1}} render={(_, item: EmployeeResponse) => {
                    let localDateTime = item.createdDateTime;
                    return <Tooltip title={localDateTime.format(DATE_WITH_TIME_FORMATER)}>
                        {localDateTime.toLocalDate().format(YEAR_MONTH_DAY_FORMATER)}
                    </Tooltip>
                }}/>

                {employeeAuthorizationStore.hasAuthority("人员_修改") ?
                    <Table.Column title={"操作"} key={"actions"} render={(_, item: EmployeeResponse) => {
                        return <>
                            <Button type={"link"} onClick={() => {
                                setEditedEmployeeId(item.id)
                            }}>
                                <EditOutlined/>
                            </Button>
                            {!item.enabled && employeeAuthorizationStore.hasAuthority("人员_启用")  && <LoadableButton type={"link"} onClick={async () => {
                                await enableEmployee(item.id)
                                query()
                            }}>
                                启用
                            </LoadableButton>}
                            {item.enabled && employeeAuthorizationStore.hasAuthority("人员_禁用") &&  <LoadableButton danger type={"link"} onClick={async () => {
                                await disableEmployee(item.id)
                                query()
                            }}>
                                禁用
                            </LoadableButton>}
                        </>
                    }}/> : undefined}
            </Table>

            <ActionsDrawerLayout onClose={() => {
                setOpenAddEmployeeDrawer(false)
                setCreatedEmployeePassword(undefined)
            }} title={!createdEmployeePassword ? "新增人员" : "新增成功"} showActions={!createdEmployeePassword}
                                 onConfirm={
                                     () => addEmployeeForm.submit()
                                 } confirmLoading={createEmployeeLoading} open={openAddEmployeeDrawer}>
                {!createdEmployeePassword ?
                    <EditEmployeeForm form={addEmployeeForm} roles={roles} onFinish={(values) => {
                        setCreateEmployeeLoading(true)
                        createEmployee(values).then(response => {
                            setCreatedEmployeePassword(response.data.password)
                            query()
                        }).finally(() => {
                            setCreateEmployeeLoading(false)
                        })
                    }} loading={createEmployeeLoading}/> :
                    <Result status={"success"} title={"新增人员成功"} subTitle={`密码为:${createdEmployeePassword}`}>
                        <Button type={"primary"} onClick={() => {
                            setOpenAddEmployeeDrawer(false)
                        }}><ArrowLeftOutlined/>返回</Button>
                    </Result>}
            </ActionsDrawerLayout>
            <ActionsDrawerLayout title={"修改人员信息"} onClose={() => {
                setEditedEmployeeId(undefined)
                editEmployeeForm.resetFields()
            }} open={!!editedEmployeeData} confirmLoading={editEmployeeLoading}
                                 onConfirm={() => editEmployeeForm.submit()}>
                <EditEmployeeForm roles={roles} onFinish={values => {
                    setEditEmployeeLoading(true)

                    updateEmployee(editedEmployeeId!, values).then(() => {
                        query()
                        setEditedEmployeeId(undefined)
                    }).finally(() => {
                        setEditEmployeeLoading(false)
                    })
                }} initialData={editedEmployeeData} loading={editEmployeeLoading} form={editEmployeeForm}/>
            </ActionsDrawerLayout>
        </DataPageLayout>
    </>
}
export default observerDashboardPageWrapper(EmployeePage, "employees", "人员")
